package com.pc.cloud.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class CompressUtils {
	protected static final Logger log = LoggerFactory
			.getLogger(CompressUtils.class);

	
	public static final String compress(String input) throws Exception {
		byte[] output = compress(input.getBytes("UTF-8"));
		
		String zip = new sun.misc.BASE64Encoder().encodeBuffer(output);
		return zip;
	}
	
	public static final String uncompress(String input) throws Exception {
		byte[] output = decompress(new sun.misc.BASE64Decoder().decodeBuffer(input));
		
		String unzip = new String(output,"UTF-8");		
		
		return unzip;
	}
	
	
	/**
	 * Compress the given array of bytes.
	 */
	public static final byte[] compress(byte[] in) {
		if (in == null) {
			throw new NullPointerException("Can't compress null");
		}
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		GZIPOutputStream gz = null;
		try {
			gz = new GZIPOutputStream(bos);
			gz.write(in);
		} catch (IOException e) {
			throw new RuntimeException("IO exception compressing data", e);
		} finally {
			if (gz != null) {
				try {
					gz.close();
				} catch (IOException e) {
					log.error("Close GZIPOutputStream error", e);
				}
			}
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					log.error("Close ByteArrayOutputStream error", e);
				}
			}
		}
		byte[] rv = bos.toByteArray();
		// log.debug("Compressed %d bytes to %d", in.length, rv.length);
		return rv;
	}

	
	/**
	 * Decompress the given array of bytes.
	 * 
	 * @return null if the bytes cannot be decompressed
	 */
	public static byte[] decompress(byte[] in) {
		ByteArrayOutputStream bos = null;
		if (in != null) {
			ByteArrayInputStream bis = new ByteArrayInputStream(in);
			bos = new ByteArrayOutputStream();
			GZIPInputStream gis = null;
			try {
				gis = new GZIPInputStream(bis);

				byte[] buf = new byte[16 * 1024];
				int r = -1;
				while ((r = gis.read(buf)) > 0) {
					bos.write(buf, 0, r);
				}
			} catch (IOException e) {
				log.error("Failed to decompress data", e);
				bos = null;
			} finally {
				if (gis != null) {
					try {
						gis.close();
					} catch (IOException e) {
						log.error("Close GZIPInputStream error", e);
					}
				}
				if (bis != null) {
					try {
						bis.close();
					} catch (IOException e) {
						log.error("Close ByteArrayInputStream error", e);
					}
				}
			}
		}
		return bos == null ? null : bos.toByteArray();
	}

	public static void main(String[] args) throws Exception {
		try {
			String text = "compress  hellfjd  fdjkfdkk fdjkfdj";
			System.out.println(text.length());
			String temp = CompressUtils.compress(text);
			System.out.println(temp.length());
			
			String unzip =  CompressUtils.uncompress(temp);
			
			System.out.println(unzip);
			System.out.println(unzip.length());
		}catch(Exception e) {
			e.printStackTrace();
		} 
	}
}
